<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2018/6/6
 * Time: 17:38
 */

namespace app\common\model;

use app\common\cachemodel\ArticleCommentReply;
use think\Cache;
use think\Config;
use XznsTools\cache\CacheManage;

/**
 * 消息中西相关模型
 * Class MessageCenter
 * @package app\common\model
 */
class MessageCenter extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.app_message_center';
    public $cacheModel = 'user.message';

    /**
     * 消息中心添加消息
     * @param $uid
     * @param $messageData
     * @return bool
     */
    public function pushMessage($uid, $messageData)
    {
        try
        {
            $mid = $this->insertGetId($messageData);
            //用户消息列表缓存添加
            $this->listDataAdd((int)$uid, [$mid => $mid], $messageData['type']);
            //用户未读消息缓存添加
            CacheManage::getInstance()->setCacheConfig('user.unread_message', $uid)->listAdd([$mid => $mid], $messageData['type']);
        }
        catch (\Exception $e)
        {
            \think\Log::write('写入消息中心失败：' . $e->getMessage() . '【' . $e->getFile() . $e->getLine() . '】', 'error', true);
            return false;
        }
        return $mid;
    }

    /**
     * 更新消息数据
     * @param int $uid
     * @param int $type
     * @param array $ids
     * @param array $data
     * @return bool
     * @throws \Exception
     */
    public function UpdateData(int $uid, int $type, array $ids, array $data)
    {
        try
        {
            $where = ['id' => ['in', $ids]];
            $this->where($where)->update($data);

            foreach ($ids as $id)
            {
                //删除用户未读消息缓存
                CacheManage::getInstance()->setCacheConfig('user.unread_message', $uid)->setListKeyType($type)->delJudge($id);
                //更新消息详情缓存
                CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->setCache($data);
            }
        }
        catch (\Exception $e)
        {
            \think\Log::write('更新用户消息失败:' . $e->getMessage() . '【' . $e->getFile() . $e->getLine() . '】', 'error', true);
            return false;
        }
        return true;
    }

    /**
     * 删除消息
     * @param int $uid
     * @param int $type
     * @param array $ids
     * @param array $data
     * @return bool
     * @throws \Exception
     */
    public function DelData(int $uid, int $type, array $ids, array $data)
    {
        try
        {
            $where = ['id' => ['in', $ids]];
            $this->where($where)->update($data);
            //删除用户消息列表缓存
            $this->listDataDel($uid, $ids, $type);
            foreach ($ids as $id)
            {
                //删除用户未读消息缓存
                CacheManage::getInstance()->setCacheConfig('user.unread_message', $uid)->setListKeyType($type)->delJudge($id);
                //删除消息详情缓存
                CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->setListKeyType($type)->rmCache();
            }
        }
        catch (\Exception $e)
        {
            \think\Log::write('删除用户消息失败:' . $e->getMessage() . '【' . $e->getFile() . $e->getLine() . '】', 'error', true);
            return false;
        }
        return true;
    }

    /**
     * 获取用户所有未读消息id,用户一键已读
     * @param array $map [uid,type]
     * @return array|mixed
     * @throws \Exception
     */
    public function getAllUserMessage($map = [])
    {
        return $this->getUserUnreadMsg($map['uid'], $map['type']);
    }

    /**
     * 获取当前用户的系统 / 服务消息id(有分页)
     * @param array $map [uid,type=>1(系统消息),2(服务消息)]
     * @return array
     * @throws \Exception
     */
    public function get_user_msg_id($map = [])
    {
        return $this->getUserMsg($map['uid'], $map['type']);
    }

    /**
     * 缓存分页获取用户消息
     * @param $uid
     * @param $type
     * @return array|mixed
     * @throws \Exception
     */
    public function getUserMsg($uid, $type)
    {
        $page = input('page', 1);
        $limit = $this->pageLimit ?: Config::get('paginate.list_rows');
        $data = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel, $uid)
            ->setPage($page)
            ->setPageSize($limit)
            ->setSort('desc')
            ->setListKeyType($type)
            ->getListPage(function ($ids = [], $isCache = true, $sortType = 'desc') use ($uid, $type)
            {
                if ($isCache)
                { // 开启了缓存
                    return $this->getInfoByIdsInData($ids, [$uid, $type], $sortType);
                }
                // 没开启缓存
                return $this->getPaginateInData([$uid, $type], $sortType);
            }, 'id', [], 0, 'list', 'list_details');
        return $data;
    }

    /**
     * 获取所有用户未读的消息id
     * @param $uid
     * @param $type
     * @return array|mixed
     * @throws \Exception
     */
    public function getUserUnreadMsg($uid, $type)
    {
        $mids = CacheManage::getInstance()->setCacheConfig('user.unread_message', $uid)
            ->setListKeyType($type)
            ->ZsGetIocData('list', function () use ($uid, $type)
            {
                return $this->getUserUnreadMsgFromDms($uid, $type);
            });
        return $mids;
    }

    /**
     * 数据库获取用户所有未读消息id
     * @param $uid
     * @param $type
     * @return array
     */
    public function getUserUnreadMsgFromDms($uid, $type)
    {
        switch ($type)
        {
            case 1:
                $where['type'] = 1;
                break;
            case 2:
                $where['type'] = 2;
        }
        $where['range'] = [['=', $uid], ['=', 0], 'or'];
        $where['is_read'] = 0;

        try
        {
            $mid = $this
                ->where($where)
                ->column('id');
            $ids = [];
            foreach ($mid as $id)
            {
                $ids[$id] = $id;
            }
        }
        catch (\Exception $e)
        {
            $ids = [];// 消息列表默认为空
        }
        return $ids;
    }

    /**
     * 数据库批量获取消息
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array|void
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        if ($ids)
        {
            $where['m.id'] = ['in', $ids];
        } else
        {
            $where = ['m.range' => $type[0], 'm.type' => $type[1], 'm.status' => 0];
        }
        $field = 'm.id,m.status,m.is_read,m.range,m.type,m.article_comment_id,m.article_comment_reply_id,m.reid,m.cid,m.title,m.content,m.link,m.target,m.create_time,ac.content ac_content,ac.check_status ac_check_status,cr.content cr_content,cr.check_status cr_check_status';
        try
        {
            $data = $this
                ->alias('m')
                ->join('wechatadmin.system_article_comment ac', 'm.article_comment_id=ac.id', 'LEFT')
                ->join('wechatadmin.system_comment_reply cr', 'm.article_comment_reply_id=cr.id', 'LEFT')
                ->where($where)
                ->order('m.id', 'DESC')
                ->column($field, 'm.id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        return $data;
    }

    /**
     * 数据库分页获取用户消息
     * @param array $map
     * @param string $sortType
     * @return array|void
     */
    public function getPaginateInData($map, $sortType)
    {
        $page = input('page', 1);
        try
        {
            $where = ['m.range' => $map[0], 'm.type' => $map[1], 'm.status' => 0];
            $field = 'm.id,m.status,m.is_read,m.range,m.type,m.article_comment_id,m.article_comment_reply_id,m.reid,m.cid,m.title,m.content,m.link,m.target,m.create_time,ac.content ac_content,ac.check_status ac_check_status,cr.content cr_content,cr.check_status cr_check_status';
            try
            {
                $data = $this
                    ->alias('m')
                    ->join('wechatadmin.system_article_comment ac', 'm.article_comment_id=ac.id', 'LEFT')
                    ->join('wechatadmin.system_comment_reply cr', 'm.article_comment_reply_id=cr.id', 'LEFT')
                    ->where($where)
                    ->field($field)
                    ->order('m.id', 'DESC')
                    ->paginate(10, false, ['page' => $page])->toArray();
            }
            catch (\Exception $e)
            {
                $data = [];
            }
        }
        catch (\Exception $e)
        {
            $data = [];
        }

        return $data;
    }


    /**
     * 获取问答中心未读状态
     * @param $uid
     * @return array
     * @throws \Exception
     */
    public function getUnreadMsgNum($uid)
    {
        $res = [];
        $replyModel = new ArticleCommentReply();
        $ids = $replyModel->getUserReplyMeFromCache($uid, 0);
        // 获取回复阅读情况
        $read_ids = $replyModel->getUserReadReply($uid);
        $unread_ids = array_diff($ids, $read_ids);//评论回复未读数
        $res[] = count($unread_ids);
        //点赞未读
        $unreadGood = Cache::get('user_good_unread_status_' . $uid);
        $res[] = $unreadGood ? (int)$unreadGood : 0;
        //获取用户全部未读系统消息id
        $system_msg_id = $this->getAllUserMessage(['uid' => $uid, 'type' => 1]);
        //获取用户全部未读服务消息id
        $server_msg_id = $this->getAllUserMessage(['uid' => $uid, 'type' => 2]);
        $res[] = count($server_msg_id);//服务消息未读数
        $res[] = count($system_msg_id);//系统消息未读数
        return $res;
    }
}
